package com.tang.multi.v3;

import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author Tang
 * @classname SubReactor
 * @description [ 子 reactor ]
 * @date 2021/8/10 17:04
 */
@Slf4j
public class SubReactor implements Runnable {

    @Getter
    private Selector selector;

    @Getter
    @Setter
    SelectionKey selectionKey;

    @Getter
    private int id = 0;

    private ExecutorService executorService = Executors.newFixedThreadPool(8);

    @SneakyThrows
    public SubReactor(int id) {
        this.selector = Selector.open();
        this.id = id;
    }


    @Override
    public void run() {
        while (true) {
            try {
                int connectionLen = this.selector.select(1000);
                if (connectionLen > 0) {
                    // 监听事件
                    log.info("{}号SubRector开始处理事件...", this.id);
                    Set<SelectionKey> selectionKeys = this.selector.selectedKeys();
                    Iterator<SelectionKey> iterator = selectionKeys.iterator();
                    while (iterator.hasNext()) {
                        SelectionKey selectionKey = iterator.next();
                        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                        if (selectionKey.isReadable()) {
                            // 线程池处理数据
                            executorService.execute(new WorkHandler(socketChannel, this.selector, selectionKey));
                        }
                        iterator.remove();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}